#include "mq.h"
#include "delay.h"
#include "math.h"
 
/* ADC句柄 */
extern ADC_HandleTypeDef hadc1;


 
/**
 * @brief       设置ADC通道采样时间
 * @param       adcx : adc句柄指针,ADC_HandleTypeDef
 * @param       ch   : 通道号, ADC_CHANNEL_0~ADC_CHANNEL_17
 * @param       stime: 采样时间  0~7, 对应关系为:
 *   @arg       ADC_SAMPLETIME_1CYCLE_5, 1.5个ADC时钟周期        ADC_SAMPLETIME_7CYCLES_5, 7.5个ADC时钟周期
 *   @arg       ADC_SAMPLETIME_13CYCLES_5, 13.5个ADC时钟周期     ADC_SAMPLETIME_28CYCLES_5, 28.5个ADC时钟周期
 *   @arg       ADC_SAMPLETIME_41CYCLES_5, 41.5个ADC时钟周期     ADC_SAMPLETIME_55CYCLES_5, 55.5个ADC时钟周期
 *   @arg       ADC_SAMPLETIME_71CYCLES_5, 71.5个ADC时钟周期     ADC_SAMPLETIME_239CYCLES_5, 239.5个ADC时钟周期
 * @param       rank: 多通道采集时需要设置的采集编号,
                假设你定义channle1的rank=1，channle2 的rank=2，
                那么对应你在DMA缓存空间的变量数组AdcDMA[0] 就i是channle1的转换结果，AdcDMA[1]就是通道2的转换结果。 
                单通道DMA设置为 ADC_REGULAR_RANK_1
 *   @arg       编号1~16：ADC_REGULAR_RANK_1~ADC_REGULAR_RANK_16
 * @retval      无
 */
void adc_channel_set(ADC_HandleTypeDef *adc_handle, uint32_t ch, uint32_t rank, uint32_t stime)
{
    ADC_ChannelConfTypeDef adc_ch_conf;
    
    adc_ch_conf.Channel = ch;                            /* 通道 */
    adc_ch_conf.Rank = rank;                             /* 序列 */
    adc_ch_conf.SamplingTime = stime;                    /* 采样时间 */
    HAL_ADC_ConfigChannel(adc_handle, &adc_ch_conf);     /* 通道配置 */
}
 
/**
 * @brief       获得ADC转换后的结果
 * @param       ch: 通道值 0~17，取值范围为：ADC_CHANNEL_0~ADC_CHANNEL_17
 * @retval      无
 */
uint32_t adc_get_result(ADC_HandleTypeDef g_adc_handle,uint32_t ch)
{
//    adc_channel_set(&g_adc_handle , ch, ADC_REGULAR_RANK_1, ADC_SAMPLETIME_239CYCLES_5);    /* 设置通道，序列和采样时间 */
 
    HAL_ADC_Start(&g_adc_handle);                            /* 开启ADC */
    HAL_ADC_PollForConversion(&g_adc_handle, 500);            /* 轮询转换 */
	if(HAL_IS_BIT_SET(HAL_ADC_GetState(&g_adc_handle), HAL_ADC_STATE_REG_EOC))
    return (uint16_t)HAL_ADC_GetValue(&g_adc_handle);        /* 返回最近一次ADC1规则组的转换结果 */
}
 
/**
 * @brief       获取通道ch的转换值，取times次,然后平均
 * @param       ch      : 通道号, 0~17
 * @param       times   : 获取次数
 * @retval      通道ch的times次转换结果平均值
 */
uint32_t adc_get_result_average(ADC_HandleTypeDef g_adc_handle, uint32_t ch, uint8_t times)
{
    uint32_t temp_val = 0;
	uint32_t i = 0;
    uint8_t t;
 
    for (t = 0; t < times; t++)     /* 获取times次数据 */
    {
        temp_val += adc_get_result(g_adc_handle, ch);
        HAL_Delay(5);
    }
	i = temp_val / times;        /* 返回平均值 */
    return i;
 
}

MQ get_mq(void){
	MQ mq;
	uint32_t adcx = 0;
	float temp = 0;
	float Voll = 0;
	float RS = 0;
	float R0 = 6.64;
	
	adcx = adc_get_result_average(hadc1, ADC_CHANNEL_0, 10);
	Voll = (adcx * 5.0 / 4096);
	RS = (5 - Voll) / (Voll * 0.5);
	mq.mq2_value = pow(11.5428 * R0 / RS, 0.6549f);
	
	adcx = adc_get_result_average(hadc1, ADC_CHANNEL_1, 10);
	Voll = (adcx * 5.0 / 4096);
	RS = (5 - Voll) / (Voll * 0.5);
	mq.mq5_value = pow(11.5428 * R0 / RS, 0.6549f);
	return mq;
}

